﻿#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    this->setWindowTitle("CameraRecorder");

    this->move(200,100);
    videoLocation=QStandardPaths::writableLocation(QStandardPaths::MoviesLocation);
    recordLocation=videoLocation + "/Record";

    QDir dir(recordLocation);
    if(!dir.exists())
        dir.mkpath(recordLocation);

    display=new QLabel(this);
    display->setMinimumSize(RES_720P);
    this->setCentralWidget(display);

    timer=new QTimer(this);
    connect(timer,&QTimer::timeout,this,&MainWindow::nextFrame);

    recorder=nullptr;
    isRecording=false;

    openCamera();
}

MainWindow::~MainWindow()
{
    if(capture.isOpened())
        capture.release();

    if(writer.isOpened())
        writer.release();

    delete ui;
}

/*
int MainWindow::getCameraCount()
{
    int count=0;
    VideoCapture tmp_capture;
    for(int index=0;index < MAX_CAMERA_COUNT;index++)
    {
        tmp_capture.open(index);
        if(tmp_capture.isOpened())
            count += 1;
        tmp_capture.release();
    }
    return count;
}
*/

void MainWindow::on_actionOpen_triggered()
{
    QString fileName=QFileDialog::getOpenFileName(this,QStringLiteral("选择视频文件"),
                                                  videoLocation);
    if(fileName.isEmpty())
        return;

    capture.open(fileName.toLocal8Bit().data());
    if(capture.isOpened())
    {
        rate=capture.get(CV_CAP_PROP_FPS);
        timer->start(1000/rate);

        showVideoInfo();
    }
}

void MainWindow::nextFrame()
{
    capture >> frame;
    if(!frame.empty())
    {
        if(isRecording)
            writer << frame;

        image=convertMat2Image(frame);
        QPixmap pix=QPixmap::fromImage(image);
        if(pix.width() > RES_720P.width())
            pix=pix.scaledToWidth(RES_720P.width());
        display->setPixmap(pix);
    }
}

void MainWindow::openCamera()
{
    if(!capture.open(0))
    {
        ui->statusBar->showMessage(QStringLiteral("没有可用摄像头"));
        return;
    }

    capture.set(CV_CAP_PROP_FRAME_WIDTH, RES_720P.width());
    capture.set(CV_CAP_PROP_FRAME_HEIGHT, RES_720P.height());
    timer->start(1000/DEFAULT_FPS);
}

void MainWindow::on_actionCamera_triggered()
{
    openCamera();
}

QImage MainWindow::convertMat2Image(const Mat &cvImg)
{
    QImage qImg;
    if(cvImg.channels()==3)                             //3 channels color image
    {
        cv::cvtColor(cvImg,cvImg,CV_BGR2RGB);
        qImg =QImage((const unsigned char*)(cvImg.data),
                     cvImg.cols, cvImg.rows,
                     cvImg.cols*cvImg.channels(),
                     QImage::Format_RGB888);
    }
    else if(cvImg.channels()==1)                    //grayscale image
    {
        qImg =QImage((const unsigned char*)(cvImg.data),
                     cvImg.cols,cvImg.rows,
                     cvImg.cols*cvImg.channels(),
                     QImage::Format_Indexed8);
    }
    else
    {
        qImg =QImage((const unsigned char*)(cvImg.data),
                     cvImg.cols,cvImg.rows,
                     cvImg.cols*cvImg.channels(),
                     QImage::Format_RGB888);
    }
    return qImg;
}

void MainWindow::showVideoInfo()
{
    double rate = capture.get(CV_CAP_PROP_FPS);
    double width=capture.get(CV_CAP_PROP_FRAME_WIDTH);
    double height=capture.get(CV_CAP_PROP_FRAME_HEIGHT);
    double frameCount=capture.get(CV_CAP_PROP_FRAME_COUNT);

    QString info=QStringLiteral("帧率 ") + QString::number(rate) + QString(";")
            + QStringLiteral("帧宽 ") + QString::number(width) + QString(",")
            + QStringLiteral("帧高 ") + QString::number(height) + QString(";")
            + QStringLiteral("帧数 ") + QString::number(frameCount);

    ui->statusBar->showMessage(info);
}

void MainWindow::on_actionRecord_triggered()
{
    if(recorder == nullptr)
    {
        recorder=new Recorder(this);
        connect(recorder,&Recorder::start,this,&MainWindow::startRecord);
        connect(recorder,&Recorder::stop,this,&MainWindow::stopRecord);

        int xPos=this->x() + this->frameGeometry().width() + 10;
        recorder->move(xPos,this->y());
    }
    recorder->show();
}

void MainWindow::startRecord()
{
    if(!capture.isOpened())
        return;

    int fourcc=CV_FOURCC('X', 'V', 'I', 'D');
    QString fileName=generateRecordFile();
    writer.open(fileName.toLocal8Bit().data(),fourcc,DEFAULT_FPS,CV_RES_720P);
    isRecording=true;
}

void MainWindow::stopRecord()
{
    writer.release();
    isRecording=false;
}

QString MainWindow::generateRecordFile() const
{
    QString recordFile;
    QString currentTime=QDateTime::currentDateTime().toString("yyMMdd-hhmmss");
    recordFile=recordLocation + "/" + currentTime + QString(".avi");
    return recordFile;
}

void MainWindow::on_actionVideoLocation_triggered()
{
    QDesktopServices::openUrl(QUrl(videoLocation));
}

void MainWindow::on_actionRecordLocation_triggered()
{
    QDesktopServices::openUrl(QUrl(recordLocation));
}
